// import com.alibaba.druid.sql.ast.SQLExpr;
// import com.alibaba.druid.sql.ast.SQLExprImpl;
// import com.alibaba.druid.sql.ast.SQLObject;
// import com.alibaba.druid.sql.ast.SQLReplaceable;
// import com.alibaba.druid.sql.dialect.oracle.visitor.OracleASTVisitor;
// import com.alibaba.druid.sql.visitor.SQLASTVisitor;

// import java.util.Collections;
// import java.util.List;

#include "OracleIsSetExpr.h"
#include "../../../../ast/SQLExpr.h"
#include "../../../../ast/SQLObject.h"
#include "../../visitor/OracleASTVisitor.h"
#include "../../../../visitor/SQLASTVisitor.h"

OracleIsSetExpr::OracleIsSetExpr()
{
}

OracleIsSetExpr::OracleIsSetExpr(SQLExpr_ptr nestedTable)
{
  this->nestedTable = nestedTable;
}

SQLObject_ptr OracleIsSetExpr::clone()
{
  SQLObject_ptr clone_tmp = std::shared_ptr<OracleIsSetExpr>(new OracleIsSetExpr());
  std::shared_ptr<OracleIsSetExpr> x = std::dynamic_pointer_cast<OracleIsSetExpr>(clone_tmp);
  // OracleIsSetExpr x = new OracleIsSetExpr();
  if (nestedTable != nullptr)
  {
    x->setNestedTable(std::dynamic_pointer_cast<SQLExpr>(nestedTable->clone()));
  }
  return x;
}

// @Override
BOOL_ptr OracleIsSetExpr::replace(SQLExpr_ptr expr, SQLExpr_ptr target)
{
  if (this->nestedTable == expr)
  {
    setNestedTable(target);
    return BOOL::TRUE;
  }
  return BOOL::FALSE;
}

SQLExpr_ptr OracleIsSetExpr::getNestedTable()
{
  return nestedTable;
}

void OracleIsSetExpr::setNestedTable(SQLExpr_ptr nestedTable)
{
  if (nestedTable != nullptr)
  {
    nestedTable->setParent(SharedObject(OracleIsSetExpr));
  }
  this->nestedTable = nestedTable;
}

// @Override
void OracleIsSetExpr::accept0(SQLASTVisitor_ptr visitor)
{
  this->accept0(std::dynamic_pointer_cast<OracleASTVisitor>(visitor));
}

// @Override
void OracleIsSetExpr::accept0(OracleASTVisitor_ptr visitor)
{
  if (visitor->visit(SharedObject(OracleIsSetExpr)))
  {
    acceptChild(visitor, nestedTable);
  }
  visitor->endVisit(SharedObject(OracleIsSetExpr));
}

// @Override
SQLObject_list_ptr OracleIsSetExpr::getChildren()
{
  SQLObject_list_ptr children = std::make_shared<std::list<SQLObject_ptr>>();
  children->push_back(this->nestedTable);
  return children;
}

// @Override
int OracleIsSetExpr::hashCode()
{
  int prime = 31;
  int result = 1;
  result = prime * result + ((nestedTable == nullptr) ? 0 : nestedTable->hashCode());
  return result;
}

// @Override
bool OracleIsSetExpr::equals(Object_ptr obj)
{
  if (this == obj.get())
  {
    return true;
  }
  if (obj == nullptr)
  {
    return false;
  }
  if (getClass()->c_str() != obj->getClass()->c_str())
  {
    return false;
  }
  OracleIsSetExpr_ptr other = std::dynamic_pointer_cast<OracleIsSetExpr>(obj);
  if (nestedTable == nullptr)
  {
    if (other->nestedTable != nullptr)
    {
      return false;
    }
  }
  else if (!nestedTable->equals(other->nestedTable))
  {
    return false;
  }
  return true;
}
